package com.dkd.flow.controller;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dkd.common.annotation.Log;
import com.dkd.common.core.controller.BaseController;
import com.dkd.common.core.domain.AjaxResult;
import com.dkd.common.core.domain.entity.SysUser;
import com.dkd.common.core.page.TableDataInfo;
import com.dkd.common.enums.BusinessType;
import com.dkd.common.utils.poi.ExcelUtil;
import com.dkd.flow.domain.EProcessInstances;
import com.dkd.flow.domain.EProcessTask;
import com.dkd.flow.emums.TaskStatus;
import com.dkd.flow.mapper.EProcessDefinitionMapper;
import com.dkd.flow.service.IEProcessInstancesService;
import com.dkd.flow.service.impl.EProcessTaskServiceImpl;
import com.dkd.flow.utils.NodeUtils;
import com.dkd.system.service.impl.SysUserServiceImpl;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

/**
 * 流程实例 Controller
 *
 * @author itheima
 * @date 2025-03-02
 */
@Api(tags = "流程实例 Controller")
@RestController
@RequestMapping("/flow/instances")
public class EProcessInstancesController extends BaseController {
    @Autowired
    private IEProcessInstancesService eProcessInstancesService;
    @Autowired
    EProcessTaskServiceImpl eProcessTaskService;
    @Autowired
    SysUserServiceImpl sysUserService;
    @Autowired
    NodeUtils nodeUtils;
    @Autowired
    EProcessDefinitionMapper eProcessDefinitionMapper;

    /**
     * 查询流程实例 列表
     */
    @ApiOperation("查询流程实例 列表")
    /* @PreAuthorize("@ss.hasPermi('flow:instances:list')") */
    @GetMapping("/list")
    public TableDataInfo list(EProcessInstances eProcessInstances) {
        startPage();
        QueryWrapper queryWrapper = new QueryWrapper();
        JSONObject jsonObject = (JSONObject) JSON.toJSON(eProcessInstances);
        // 过滤掉不需要的参数params
        jsonObject.remove("params");
        jsonObject.forEach((key, value) -> {
            if (value != null) {
                if (key == "createTime") {
                    queryWrapper.like("create_time",
                            new SimpleDateFormat("yyyy-MM-dd").format(eProcessInstances.getCreateTime()));
                } else {
                    queryWrapper.eq(key,
                            value);
                }
            }
        });
        List<EProcessInstances> list = eProcessInstancesService.list(queryWrapper);
        return getDataTable(list);
    }

    /**
     * 导出流程实例 列表
     */
    @ApiOperation("导出流程实例 列表")
    @PreAuthorize("@ss.hasPermi('flow:instances:export')")
    @Log(title = "流程实例 ", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response,
            EProcessInstances eProcessInstances) {
        List<EProcessInstances> list = eProcessInstancesService.selectEProcessInstancesList(eProcessInstances);
        ExcelUtil<EProcessInstances> util = new ExcelUtil<EProcessInstances>(EProcessInstances.class);
        util.exportExcel(response,
                list,
                "流程实例 数据");
    }

    /**
     * 获取流程实例 详细信息
     */
    @ApiOperation("获取流程实例 详细信息")
    @PreAuthorize("@ss.hasPermi('flow:instances:query')")
    @GetMapping(value = "/{ID}")
    public AjaxResult getInfo(
            @PathVariable("ID") Long ID) {
        return success(eProcessInstancesService.selectEProcessInstancesByID(ID));
    }

    /**
     * 新增流程实例
     */
    @ApiOperation("新增流程实例 ")
    @PreAuthorize("@ss.hasPermi('flow:instances:add')")
    @Log(title = "流程实例 ", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(
            @RequestBody JSONObject data) {
        return success(eProcessInstancesService.insertEProcessInstances(data));
    }

    /**
     * 修改流程实例
     */
    @ApiOperation("修改流程实例 ")
    /* @PreAuthorize("@ss.hasPermi('flow:instances:edit')") */
    @Log(title = "流程实例 ", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(
            @RequestBody JSONObject data) {
        Long taskId = eProcessInstancesService.updateEProcessInstances(data);
        JSONObject jsonObject = new JSONObject();
        if (taskId != null) {
            jsonObject.put("curTaskId",
                    taskId);
        }
        EProcessTask eProcessTask = eProcessTaskService.getTaskDetail(jsonObject);
        return success(eProcessTask);
    }

    @ApiOperation("查询实例任务，按时间排序，拼接成任务日志")
    @GetMapping(value = "/getLog/{ID}")
    public AjaxResult getLog(
            @PathVariable("ID") Long ID) {
        EProcessInstances eProcessInstances = eProcessInstancesService.selectEProcessInstancesByID(ID);
        Long processDefinitionId = eProcessInstances.getProcessDefinitionId();
        JSONObject relations = nodeUtils.initRelationsByData(processDefinitionId);
        ArrayList<JSONObject> nodes = (ArrayList<JSONObject>) relations.get("nodes");
        // Step 1: 查询数据
        QueryWrapper<EProcessTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PROCESS_INSTANCES_ID",
                ID);
        List<EProcessTask> eProcessTaskList = eProcessTaskService.list(queryWrapper);
        // Step 2: 排序逻辑
        eProcessTaskList.sort((task1, task2) -> {
            // 1. 创建时间优先（升序）
            int timeCompare = task1.getCreateTime()
                    .compareTo(task2.getCreateTime());
            if (timeCompare != 0) {
                return timeCompare;
            }
            // 2. 创建时间相同，按任务状态优先级排序（long 类型）
            long status1 = task1.getTaskStatus();
            long status2 = task2.getTaskStatus();
            int priority1;
            int priority2;
            if (status1 == TaskStatus.INITIATE_APPLICATION.getValue()
                    .longValue()) {
                priority1 = 0;
            } else if (status1 == TaskStatus.UNDER_APPROVAL.getValue()
                    .longValue()) {
                priority1 = 2;
            } else {
                priority1 = 1;
            }
            if (status2 == TaskStatus.INITIATE_APPLICATION.getValue()
                    .longValue()) {
                priority2 = 0;
            } else if (status2 == TaskStatus.UNDER_APPROVAL.getValue()
                    .longValue()) {
                priority2 = 2;
            } else {
                priority2 = 1;
            }
            return Integer.compare(priority1,
                    priority2);
        });
        // Step 3: 转换为 JSON
        List<JSONObject> newEProcessTaskList = eProcessTaskList.stream()
                .map(eProcessTask -> {
                    String processDesignId = eProcessTask.getProcessDesignId();
                    Boolean counterSign = nodeUtils.getCounterSignByNodeList(processDesignId,
                            nodes);
                    String title = nodeUtils.getTitle(processDesignId,
                            nodes);
                    SysUser approverUser = sysUserService.selectUserById(eProcessTask.getApprover());
                    JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(eProcessTask));
                    jsonObject.put("user",
                            JSONObject.parseObject(JSONObject.toJSONString(approverUser)));
                    jsonObject.put("counterSign",
                            counterSign);
                    jsonObject.put("title",
                            title);
                    return jsonObject;
                })
                .collect(Collectors.toList());
        return success(newEProcessTaskList);
    }

    /**
     * 删除流程实例
     */
    @ApiOperation("删除改流程实例 ")
    @PreAuthorize("@ss.hasPermi('flow:instances:remove')")
    @Log(title = "流程实例 ", businessType = BusinessType.DELETE)
    @DeleteMapping("/{IDs}")
    public AjaxResult remove(
            @PathVariable Long[] IDs) {
        return toAjax(eProcessInstancesService.deleteEProcessInstancesByIDs(IDs));
    }
}
